package com.cloudwise.pollux.service.gateway.exception;

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义sentinel异常返回信息
 * @author sky
 * @date 2021/2/3 3:34 下午
 */
@Component
public class CustomerBlockHandler implements BlockRequestHandler {

//    @Override
//    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
//
//    }

    @PostConstruct
    public void init() {
        new CustomerBlockHandler();
    }

    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
        Throwable e = throwable;
        SentinelErrorMsg sentinelErrorMsg = new SentinelErrorMsg();
        if (e instanceof FlowException) {
            sentinelErrorMsg.setMsg("接口限流了");
            sentinelErrorMsg.setStatus(101);
        } else if (e instanceof DegradeException) {
            sentinelErrorMsg.setMsg("服务降级了");
            sentinelErrorMsg.setStatus(102);
        } else if (e instanceof ParamFlowException) {
            sentinelErrorMsg.setMsg("热点参数限流了");
            sentinelErrorMsg.setStatus(103);
        } else if (e instanceof SystemBlockException) {
            sentinelErrorMsg.setMsg("系统规则（负载/...不满足要求）");
            sentinelErrorMsg.setStatus(104);
        } else if (e instanceof AuthorityException) {
            sentinelErrorMsg.setMsg("授权规则不通过");
            sentinelErrorMsg.setStatus(105);
        }else {
            sentinelErrorMsg.setMsg("限流");
            sentinelErrorMsg.setStatus(107);
        }
        // spring mvc自带的json操作工具，叫jackson
        return ServerResponse.status(HttpStatus.OK)
                    .contentType(MediaType.APPLICATION_JSON_UTF8)
                    .body(BodyInserters.fromObject(sentinelErrorMsg));
    }

    @Data
    static class SentinelErrorMsg {
        private Integer status;
        private String msg;
    }
}
